package edu.udo.sopra10.chaturaji.entities;

import static edu.udo.sopra10.chaturaji.util.ExceptionUtil.assertNotNull;
import static org.apache.commons.lang.builder.ToStringStyle.SHORT_PREFIX_STYLE;

import org.apache.commons.lang.builder.ToStringBuilder;

import edu.udo.sopra10.chaturaji.entities.coordinates.Coordinate;
import edu.udo.sopra10.chaturaji.entities.coordinates.Position;
import edu.udo.sopra10.chaturaji.entities.pieces.Piece;

/**
 * A single tile on the {@link Game} board. This links {@link Coordinate}
 * information and the {@link Piece}s that may or may not reside on the square.
 * 
 * @author Simon Dierl
 */
public final class Square {
	/**
	 * The game to whose board the square belongs.
	 */
	private AbstractGame game;

	/**
	 * The piece standing on the square, {@code null} if empty.
	 */
	private Piece piece;

	/**
	 * The coordinates of the square on the board.
	 */
	private Position position;

	/**
	 * Create a new square in the specified game on the specified position.
	 * 
	 * @param game
	 *            the game to whose board the square shall belong-
	 * @param position
	 *            the position on the game board.
	 */
	public Square(final AbstractGame game, final Position position) {
		setGame(game);
		setPosition(position);
	}

	/**
	 * Get the {@link Game} on whose board this square is situated.
	 * 
	 * @return the game on whose board this square is situated, never
	 *         {@code null}.
	 */
	public AbstractGame getGame() {
		return game;
	}

	/**
	 * Get the piece (or lack thereof) on this square.
	 * 
	 * @return the piece occupying this square or {@code null} if the square is
	 *         unoccupied.
	 */
	public Piece getPiece() {
		return piece;
	}

	/**
	 * Get this squares {@link Position} on the game board.
	 * 
	 * @return this squares position, never {@code null}.
	 */
	public Position getPosition() {
		return position;
	}

	/**
	 * Set the {@link Game} on whose board this square is located.
	 * 
	 * @param game
	 *            the new game on whose board this square is located, must not
	 *            be {@code null}.
	 */
	public void setGame(final AbstractGame game) {
		this.game = assertNotNull(game, "game");
	}

	/**
	 * Set the piece (or lack thereof) on this square.
	 * 
	 * @param piece
	 *            the new piece occupying this square or {@code null} if the
	 *            square is now empty.
	 */
	public void setPiece(final Piece piece) {
		this.piece = piece;
	}

	/**
	 * Set the {@link Position} of this square on the {@link Game} board.
	 * 
	 * @param position
	 *            this square's new position, must nor be {@code null}.
	 */
	public void setPosition(final Position position) {
		this.position = assertNotNull(position, "position");
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this, SHORT_PREFIX_STYLE).append("position",
				position).toString();
	}
}
